package com.kuang.stacksAndQueues;

import java.util.Stack;

/**
 * @author kjx
 */
/*
给定一个经过编码的字符串，返回它解码后的字符串。
编码规则为: k[encoded_string]，表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的；输入字符串中没有额外的空格，且输入的方括号总是符合格式要求的。
此外，你可以认为原始数据不包含数字，所有的数字只表示重复的次数 k ，例如不会出现像 3a 或 2[4] 的输入。

示例 1：
输入：s = "3[a]2[bc]"
输出："aaabcbc"

示例 2：
输入：s = "3[a2[c]]"
输出："accaccacc"

示例 3：
输入：s = "2[abc]3[cd]ef"
输出："abcabccdcdcdef"

示例 4：
输入：s = "abc3[cd]xyz"
输出："abccdcdcdxyz"
* */
public class DecodeString {
    //自己做的，永远不要拿数组当 temp 了！！！！！！！！！！！！！！！！！！！！！！！！
    //拿数组当temp，因为数组长度固定，你没有写入的数据全部会变成可以算的混乱值，这些丢到里面就会造成毁灭的bug
    //而且tm还要遍历，我抄你妈，再用是狗
    public static String decodeString(String s) {
        Stack<Character> stack = new Stack<>();
        char[] preChar = s.toCharArray();     //输入字符串转数组
        StringBuilder result = new StringBuilder();

        for (char value : preChar) {
            String tempStr;     //用于暂存的字符串
            StringBuilder tempCharStr = new StringBuilder();   //用于暂存字符的字符串
            StringBuilder tempIntStr = new StringBuilder();    //用于暂存数字的字符串
            stack.push(value);
            //如果出现了 "]"，代表出现了完整的一个需要转化的元组
            if (stack.peek().equals(']')) {
                //先处理括号内的字符
                stack.pop();    //把括号排除
                while (!stack.peek().equals('[')) {
                    tempCharStr.append(stack.pop());
                }

                //再处理括号外的数字
                stack.pop();    //把括号排除
                while (!stack.isEmpty() && !Character.isLetter(stack.peek()) && stack.peek() != '[') {
                    //当不为空栈且栈顶元素不是字母，如果是字母代表这个元组结束了
                    tempIntStr.append(stack.pop());
                }
                //将数字字符串和字符字符串反转运算并重新压栈
                tempStr = reverseAndRepeat(Integer.parseInt(reverseString(tempIntStr.toString())), reverseString(tempCharStr.toString()));
                for (int i = 0; i < tempStr.length(); i++) {
                    stack.push(tempStr.charAt(i));
                }
            }
        }

        while (!stack.isEmpty()){
            result.append(stack.pop());
        }

        return reverseString(result.toString());
    }




    //输入数字3和字符串"cba"将返回字符串"cbacbacba"
    public static String reverseAndRepeat(int repeatTimes, String str) {
        // 重复字符串
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < repeatTimes; i++) {
            result.append(str);
        }

        return result.toString();
    }

    //反转字符串
    public static String reverseString(String input) {
        StringBuilder reversed = new StringBuilder();

        for (int i = input.length() - 1; i >= 0; i--) {
            reversed.append(input.charAt(i));
        }

        return reversed.toString();
    }


    public static void main(String[] args) {
        System.out.println(decodeString("3[z]2[2[y]pq4[2[jk]e1[f]]]ef"));
    }
}
